home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / FILER / SMART.ZIP / !SmartDir / c / module < prev    next >
Text File  |  1997-10-21  |  6KB  |  244 lines

  1. /* Produces module version of SmartOpenDir */
  2. #include <ctype.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "kernel.h"
  6. #include "OS:filer.h"
  7. #include "OS:filter.h"
  8. #include "pattern.h"
  9. #include "module.h"
  10. #include "ftask.h"
  11. #include "cmos.h"
  12.  
  13. static bool alias_set = FALSE;
  14.  
  15. static os_error rmload_syntax_error = {0,
  16.     "SmartOpenDir load parameter syntax: [-a] -f <filename>"};
  17.  
  18. static os_error loadpatterns_error = {0,
  19.     "SmartOpenDirLoad: "
  20.     "You must specify a filename"};
  21.  
  22. static os_error no_filer_error = {0,
  23.     "SmartOpenDir: "
  24.     "Task Filer not found"};
  25.  
  26. static const char Alias_Filer_OpenDir[] = "Alias$Filer_OpenDir";
  27. static const char SmartOpenDirAlias[] = "SmartOpenDir %*0";
  28. static const char SmartOpenDir[] = "SmartOpenDir";
  29.  
  30. static bool post_filter_set = FALSE;
  31. static wimp_t filer_task = 0;
  32. #define FILTER_MASK (~((1<<3) + (1<<6) + (1<<17) + (1<<18)))
  33.  
  34. os_error const *finalise(int fatal, int podule, void *pw)
  35. {
  36.   fatal=fatal; podule=podule;
  37.  
  38.   if (cmos_changed)
  39.     cmos_restore();
  40.  
  41.   free_patterns();
  42.  
  43.   if (alias_set)
  44.     xos_set_var_val(Alias_Filer_OpenDir, 0, -1 /* Destroy */,
  45.         0, 4 /* Literal string */, 0, 0);
  46.  
  47.   if (post_filter_set)
  48.   {
  49.     xfilter_de_register_post_filter(SmartOpenDir,
  50.         (void const *) (int) post_filter_veneer,    /* Yeuch */
  51.         pw, filer_task, FILTER_MASK);
  52.     post_filter_set = FALSE;
  53.   }
  54.  
  55.   return 0;
  56. }
  57.  
  58. typedef enum {
  59.   command_SmartOpenDir,
  60.   command_SmartOpenDirLoad
  61. } command_numbers;
  62.  
  63. os_error const *command(char *args, int argc, int cmd_no, void *pw)
  64. {
  65.   os_error const *e;
  66.   char *newcom;
  67.  
  68.   pw=pw;
  69.  
  70.   switch (cmd_no)
  71.   {
  72.     case command_SmartOpenDir:
  73.       if (cmos_changed)
  74.         cmos_restore();
  75.       e = convert_command(args, &newcom);
  76.       if (newcom)
  77.         e = xos_cli(newcom);
  78.       return e;
  79.     case command_SmartOpenDirLoad:
  80.       if (argc != 1)
  81.         return &loadpatterns_error;
  82.       return load_patterns(args);
  83.   }
  84.  
  85.   return 0;
  86. }
  87.  
  88. static os_error const *set_filter(void *pw)
  89. {
  90.   os_error const *e = find_named_task("Filer", &filer_task);
  91.   if (e)
  92.     return e;
  93.   if (!filer_task)
  94.     return &no_filer_error;
  95.   e = xfilter_register_post_filter(SmartOpenDir,
  96.       (void const *) (int) post_filter_veneer,    /* Yeuch */
  97.       pw, filer_task, FILTER_MASK);
  98.   if (e)
  99.     return e;
  100.   post_filter_set = TRUE;
  101.   return 0;
  102. }
  103.  
  104. static char *CRstrterm(char *s)
  105. {
  106.   int n;
  107.   if (!s) return s;
  108.   for (n=0; s[n]>31; ++n);
  109.   s[n] = 0;
  110.   return s;
  111. }
  112.  
  113. extern int post_filter_handler(_kernel_swi_regs *r, void *pw)
  114. {
  115.   wimp_pointer ptrinfo;
  116.   wimp_block const *e = (wimp_block const *) r->r[1];
  117.  
  118.   pw = pw;
  119.  
  120.   if (cmos_changed)
  121.     cmos_restore();
  122.   switch (r->r[0])
  123.   {
  124.     case 3:
  125.       xwimp_get_pointer_info(&ptrinfo);
  126.       if (ptrinfo.buttons == 1)
  127.       {
  128.           /* Read title bar to open parent */
  129.         wimp_window_info winfo;
  130.  
  131.         winfo.w = e->close.w;
  132.         if (!xwimp_get_window_info_header_only(&winfo))
  133.         {
  134.           char *leaf =
  135.               strrchr(CRstrterm(winfo.title_data.indirected_text.text), '.');
  136.           if (leaf)
  137.           {
  138.             *leaf = 0;
  139.             match_and_set(winfo.title_data.indirected_text.text);
  140.             *leaf = '.';
  141.           }
  142.         }
  143.       }
  144.       break;
  145.     case 17:
  146.     case 18:
  147.       switch (e->message.action)
  148.       {
  149.         case 5:    /* Message_DataOpen */
  150.           if (e->message.data.data_xfer.file_type == 0x1000)    /* Directory */
  151.             match_and_set(e->message.data.data_xfer.file_name);
  152.           break;
  153.         case 0x400:    /* Message_FilerOpenDir */
  154.           match_and_set(
  155.               ((filer_message_open_dir *) &e->message.data)->dir_name);
  156.           break;
  157.         case 0x402:    /* Message_FilerOpenDirAt */
  158.           match_and_set(
  159.               ((filer_message_open_dir_at *) &e->message.data)->dir_name);
  160.           break;
  161.       }
  162.       break;
  163.   }
  164.   return 1;    /* Behave as if we haven't claimed an interrupt
  165.              to make veneer return MOVS pc, lr */
  166. }
  167.  
  168. #define MAXINITARGS 4
  169.  
  170. const os_error *initialise(const char *cmd_tail, int len, void *pw)
  171. {
  172.   char *args;
  173.   int argc;
  174.   char *argv[MAXINITARGS];
  175.   int i;
  176.   const os_error *e;
  177.  
  178.   /* Make writable version of cmd_tail */
  179.   len = strlen(cmd_tail);
  180.   args = malloc(len + 1);
  181.   if (!args)
  182.     return &nomem_error;
  183.   memcpy(args, cmd_tail, len + 1);
  184.  
  185.   /* Split up args into argv */
  186.   argc = 0;
  187.   for (i = 0; i < len; ++i)
  188.   {
  189.     while (isspace(args[i])) ++i;
  190.     if (!iscntrl(args[i]) && argc == MAXINITARGS)
  191.       return &rmload_syntax_error;
  192.     argv[argc++] = args + i;
  193.     while (i < len && !isspace(args[i])) ++i;
  194.     args[i] = 0;
  195.   }
  196.  
  197.   /* Process argv */
  198.   for (i = 0; i < argc; ++i)
  199.   {
  200.     if (argv[i][0] == '-')
  201.     {
  202.       switch (argv[i][1])
  203.       {
  204.         case 'a':
  205.           if (!xos_set_var_val(Alias_Filer_OpenDir,
  206.               (byte const *) SmartOpenDirAlias,
  207.               sizeof(SmartOpenDirAlias) - 1,
  208.               0, 4 /* Literal string */, 0, 0))
  209.             alias_set = TRUE;
  210.           break;
  211.         case 'f':
  212.           if (++i == argc)
  213.             return &rmload_syntax_error;
  214.           e = load_patterns(argv[i]);
  215.           if (e)
  216.             return e;
  217.           break;
  218.         default:
  219.           return &rmload_syntax_error;
  220.       }
  221.     }
  222.     else
  223.       return &rmload_syntax_error;
  224.   }
  225.   free(args);
  226.   return set_filter(pw);
  227. }
  228.  
  229. void service_handler(int sn, _kernel_swi_regs *r, void *pw)
  230. {
  231.   r=r;
  232.  
  233.   switch (sn)
  234.   {
  235.     case 0x87:    /* FilterManagerInstalled */
  236.       if (!post_filter_set)
  237.         set_filter(pw);
  238.       break;
  239.     case 0x88:    /* FilterManagerDying */
  240.       post_filter_set = FALSE;
  241.       break;
  242.   }
  243. }
  244.